/*
* Conditions Of Use
*
* This software was developed by employees of the Sigmatrix(Beijing) Corporation.
* This software is provided by sigmatrix as a service and is expressly
* provided "AS IS."  Sigmatrix MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
* AND DATA ACCURACY.  Sigmatrix does not warrant or make any representations
* regarding the use of the software or the results thereof, including but
* not limited to the correctness, accuracy, reliability or usefulness of
* the software.
*
* Permission to use this software is contingent upon your acceptance
* of the terms of this agreement.
*
*/
package com.sigmatrix.h5.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.microsoft.windowsazure.exception.ServiceException;
import com.sigmatrix.h5.components.FeignManager;
import com.sigmatrix.h5.dao.DisTerminalShopDao;
import com.sigmatrix.h5.dto.DisTerminalShopData;
import com.sigmatrix.h5.entity.DisDealer;
import com.sigmatrix.h5.entity.DisDealerAcct;
import com.sigmatrix.h5.entity.DisDealerAcctRegAudit;
import com.sigmatrix.h5.entity.DisRebateScanCode;
import com.sigmatrix.h5.entity.DisTerminalShop;
import com.sigmatrix.h5.entity.DisTerminalShopDetail;
import com.sigmatrix.h5.enums.ApplyStatus;
import com.sigmatrix.h5.enums.ApplyType;
import com.sigmatrix.h5.enums.CoordType;
import com.sigmatrix.h5.enums.ShopType;
import com.sigmatrix.h5.exception.MessageException;
import com.sigmatrix.h5.service.AdminAreaService;
import com.sigmatrix.h5.service.DisDealerAcctRegAuditService;
import com.sigmatrix.h5.service.DisDealerAcctService;
import com.sigmatrix.h5.service.DisDealerService;
import com.sigmatrix.h5.service.DisRebateScanCodeService;
import com.sigmatrix.h5.service.DisTerminalShopDetailService;
import com.sigmatrix.h5.service.DisTerminalShopService;
import com.sigmatrix.h5.utils.Assert;
import com.sigmatrix.h5.utils.CommonUtils;
import com.sigmatrix.h5.utils.Cons;
import com.sigmatrix.h5.utils.Constants;
import com.sigmatrix.h5.utils.MD5Utils;
import com.sigmatrix.h5.utils.SessionUtils;
import com.sigmatrix.h5.utils.Utils;
import com.sigmatrix.h5.utils.baidu.BaiduMapUtils;
import com.sigmatrix.h5.utils.baidu.po.LatLngLocation;
import com.sigmatrix.h5.web.args.RegistTerminalShopParam;
import com.sigmatrix.h5.web.args.TerminalShopInfoResponse;
import com.sigmatrix.h5.web.mode.SigmatrixLocationWrapper;
import com.sigmatrix.sc.jdbc.common.service.ServiceImpl;


/**
 *@ClassName: DisTerminalShopServiceImpl
 *@Description: 
 *@author MH
 *@date 2017年8月14日 上午10:42:25
 */
@Service
public class DisTerminalShopServiceImpl extends ServiceImpl<DisTerminalShop,Integer> implements DisTerminalShopService{
	
	private Logger logger = Logger.getLogger(DisTerminalShopServiceImpl.class);
	
	@Autowired
	private DisTerminalShopDao disTerminalShopDao;
	
	@Autowired
	private DisTerminalShopDetailService disTerminalShopDetailService;
	
	@Autowired
	private FeignManager feignManager;
	
	@Autowired
	private DisDealerAcctRegAuditService distributionAcctRegAuditService;
	
	@Autowired
	private DisRebateScanCodeService disRebateScanCodeService;
	
	@Autowired
	private AdminAreaService adminAreaService;
	
	@Autowired
	private DisDealerService disDealerService;
	
	@Autowired
	private DisDealerAcctService disDealerAcctService;
	
	@Autowired
	private DisDealerAcctRegAuditService disDealerAcctRegAuditService;
	
//	@Autowired
//	private WeChatSmallProgramService weChatSmallProgramService;
//	
	@Override
	public List<DisTerminalShop> findByOpenId(String openId){
		return disTerminalShopDao.findByOpenId(openId);
		
	}
	/**
	 * 
	 *@Title: genShopCode
	 *@Description: 生成终端门店编码
	 *@return String
	 *@author MH
	 *@date 2017年10月23日 下午3:10:54
	 *@return
	 */
	@Override
	public String genShopCode(){
		try{
			final StringBuffer result = new StringBuffer("TS");
			String sequence = feignManager.sequence(SessionUtils.getEseCode(), "TS", "0000")+"";
			final StringBuffer seqStr = new StringBuffer("");
			if(sequence.length()>5){
				logger.error("终端店编码sequence长度大于5位");
				return null;
			}
			while(seqStr.length() < (5-sequence.length())){
				seqStr.append("0");
			}
			seqStr.append(sequence);
			result.append(seqStr.toString());
			return result.toString();
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 
	 *@Title: gpsLoaction
	 *@Description: 经纬度定位
	 *@return void
	 *@author MH
	 *@date 2017年10月23日 下午3:11:15
	 *@param shop
	 *@throws ServiceException
	 */
	@Override
	public void gpsLoaction(DisTerminalShop shop){
		//根据经纬度获取地址
//		LatLngLocation location = BaiduMapUtils.parseLatAndLng(shop.getLat(), shop.getLng(),CoordType.GCJ02LL);
//		gpsLoaction(shop, location);
		SigmatrixLocationWrapper location2 = adminAreaService.getLocation(shop.getLat(), shop.getLng());
		shop.setAddress(location2.getAddress());
		shop.setCity(location2.getCity());
		shop.setProvince(location2.getProvince());
		shop.setCitySubOrdinate(location2.getCitySubOrdinate());
	}
	@Override
	public void gpsLoaction(DisTerminalShop shop,LatLngLocation location){
		
		SigmatrixLocationWrapper location2 = adminAreaService.getLocation(shop.getLat(), shop.getLng());
		shop.setAddress(location2.getAddress());
		shop.setCity(location2.getCity());
		shop.setProvince(location2.getProvince());
		shop.setCitySubOrdinate(location2.getCitySubOrdinate());
//		
//		//根据经纬度获取地址
//		if(CommonUtils.isEmpty(location)) throw new MessageException("定位失败");
//		if(BaiduMapStatus.OK.checkValue(location.getStatus())){
//			List<AdminArea> areas = adminAreaService.findByAllByCache();
//			Assert.notNull(areas, "查询行政区划失败");
//			AddressComponent addr = location.getResult().getAddressComponent();
//			if(CommonUtils.isEmpty(addr)) throw new MessageException("定位失败");
//			//根据地点名称获取地点ID
//			for (AdminArea area : areas) {
//				int i =0;
//				if(addr.getCity().contains(area.getName())){
//					shop.setCity(area.getId());
//					shop.setProvince(area.getParent());
//					i++;
//				}
//				if(addr.getDistrict().contains(area.getName())){
//					shop.setCitySubOrdinate(area.getId());
//					i++;
//				}
//				if(i >= 2){
//					break;
//				}
//			}
//			//TODO 暂时是查数据库，以后改为缓存
//			if(CommonUtils.isEmpty(shop.getCity()) && CommonUtils.isNotEmpty(shop.getCitySubOrdinate())) {
//				AdminArea citySub = adminAreaService.findById(shop.getCitySubOrdinate());
//				if(CommonUtils.isEmpty(citySub))return;
//				AdminArea city = adminAreaService.findById(citySub.getParent());
//				if(CommonUtils.isNotEmpty(city)) {
//					shop.setCity(city.getId());
//					AdminArea province = adminAreaService.findById(city.getParent());
//					if(CommonUtils.isNotEmpty(province))shop.setProvince(province.getId());
//				}
//			}
//			shop.setAddress(location.getResult().getFormattedAddress());
//		}else{
//			throw new MessageException("定位失败");
//		}
		
	}

	@Override
	public DisTerminalShop findByName(String name) {
		
		return disTerminalShopDao.findByName(name);
	}

	@Override
	public DisTerminalShop findByCode(String code) {
		DisTerminalShop shop = new DisTerminalShop();
		shop.setCode(code);
		List<DisTerminalShop> list = select(shop);
		return CommonUtils.isEmpty(list)?null:list.get(0);
	}

	@Override
	@Transactional
	public DisTerminalShop directSave(RegistTerminalShopParam vo) {
		DisTerminalShop shop = validateShopAttr(vo);
		if(CommonUtils.isNotEmpty(shop))return shop;
		shop = new DisTerminalShop();
		BeanUtils.copyProperties(vo, shop);
		//GPS定位
//		LatLngLocation location = BaiduMapUtils.parseLatAndLng(vo.getLat(), vo.getLng(), CoordType.GCJ02LL);
//		gpsLoaction(shop, location);
		gpsLoaction(shop);
		shop.setType(vo.getShopType() == null?ShopType.GROCERY_STORE.value:vo.getShopType().value);
		shop.setCode(genShopCode());
		shop.setCreateTime(new Date());
		shop.setEnterpriseId(SessionUtils.getEseId());
		shop.setStatus(Constants.STATUS_ENABLE);
		//保存明细
		Integer shopId = insertSelective(shop);
		shop.setId(shopId);
		disTerminalShopDetailService.create(shop,null,vo.getOpenId());
		//保存扫码记录
		saveScanRecord(vo);
		return shop;
	}
	private void saveScanRecord(RegistTerminalShopParam param){
		DisRebateScanCode _scan = new DisRebateScanCode();
		_scan.setPromotionCode(param.getPromotionCode());
		_scan.setUrlDomain(param.getUrlDomain());
		_scan.setOpenId(param.getOpenId());
		_scan.setQrCode(param.getTagCode());
		_scan.setSeqNum(param.getSeqNum()+"");
		_scan.setAccount(SessionUtils.getAccount());
		_scan.setStatus(Constants.STATUS_ENABLE);
		_scan.setCodeType(Constants.CODE_TYPE_X);
		_scan.setScanTime(new Date());
		disRebateScanCodeService.insertSelective(_scan);
	}
	private DisTerminalShop validateShopAttr(RegistTerminalShopParam vo){
		Assert.notNull(vo.getOpenId(), "openId不能为空");
		Assert.notNull(vo.getName(), "终端店名称不能为空");
		//Assert.notNull(vo.getTagCode(), "码内容不能为空");
		Assert.notNull(vo.getLat(), vo.getLng(),"经纬度不能为空");
		List<DisTerminalShopDetail> detail = disTerminalShopDetailService.findByOpenId(vo.getOpenId());
		if(CommonUtils.isNotEmpty(detail))throw new MessageException("你已经注册过门店");
		List<DisTerminalShop> shops = findByOpenId(vo.getOpenId());
		if(CommonUtils.isNotEmpty(shops)) return shops.get(0);;
		
		return null;
	}

	@Override
	public DisTerminalShop getLastApplyInfo(String openId) {
		DisDealerAcctRegAudit audit = distributionAcctRegAuditService.findLastByOpenId(openId);
		if(CommonUtils.isNotEmpty(audit)){
			return findByCode(audit.getAccount());
		}else{
			List<DisTerminalShopDetail> list = disTerminalShopDetailService.findByOpenId(openId);
			if(CommonUtils.isNotEmpty(list)){
				return findById(list.get(0).getTerminalShopId());
			}
		}
		return null;
	}
	@Override
	public DisTerminalShop findByOpenIdAndDealerId(String openId, Integer dealerId) {
		return disTerminalShopDao.findByOpenIdAndDealerId(openId,dealerId);
	}
	
	@Override
	public DisTerminalShop registShop(RegistTerminalShopParam vo) {
		logger.info("注册终端门店（审核+创建crm）="+JSONObject.toJSONString(vo));
		validateShopParam(vo);
		final DisTerminalShop shop = new DisTerminalShop();
		BeanUtils.copyProperties(vo, shop);
		//新添终端门店类型
		if(CommonUtils.isNotEmpty(vo.getShopType())){
			shop.setType(vo.getShopType().value);
		}else{
			shop.setType(ShopType.GROCERY_STORE.value);
		}
		shop.setEnterpriseId(SessionUtils.getEseId());
		shop.setStatus(Constants.TERMINAL_SHOP_STATUS_NO_AUDIT);
		shop.setCode(genShopCode());
		shop.setCreateTime(new Date());
		Assert.notNull(vo.getSmallOpenId(),"小程序端注册请指定小程序openId");
		shop.setSmallOpenId(vo.getSmallOpenId());
		Integer dealerId = getDealerId(vo.getPromotionCode());
		DisDealer dealer = disDealerService.findById(dealerId);
		Assert.notNull(dealer, "未查询到经销商");
		shop.setDealerId(dealerId);
		LatLngLocation location = BaiduMapUtils.parseLatAndLng(vo.getLat(), vo.getLng(),CoordType.GCJ02LL);
		Assert.notNull(location, "GPS定位失败");
		//校验是否窜货
		if(! disDealerService.checkFleeing(dealer.getId(), location))throw new MessageException("GPS定位的地点没有在该经销商的销售区域内");
		//确定门店的省市区县
		gpsLoaction(shop, location);
		//添加到待审核记录
		addAudit(shop, dealer,MD5Utils.getMD5Code(vo.getPassWord()));
		disTerminalShopDao.insertSelective(shop);
		return shop;
	}
	
	public static void main(String args []) {
		System.out.println(JSON.toJSONString( BaiduMapUtils.parseLatAndLng("30.448761","106.63161",CoordType.GCJ02LL)));
	}
	private void addAudit(DisTerminalShop shop, DisDealer dealer, String passWord) {
		DisDealerAcctRegAudit audit = new DisDealerAcctRegAudit();
		if(CommonUtils.isNotEmpty(dealer)) {
			audit.setDealerId(dealer.getId());
			audit.setDealerName(dealer.getName());
		}
		audit.setApplyType(ApplyType.SHOP.value);
		audit.setStatus(ApplyStatus.NO_AUDIT.value);
		audit.setAccount(shop.getCode());
		audit.setPwd(passWord);
		audit.setContact(shop.getMobilePhone());
		audit.setTerminalName(shop.getName());
		audit.setName(shop.getContact());
		audit.setSmallOpenId(shop.getSmallOpenId());
		audit.setOpenId(shop.getOpenId());
		audit.setRemarks(shop.getRemarks());
		audit.setApplyTime(new Date());
		disDealerAcctRegAuditService.insertSelective(audit);
	}
	/**
	 * 推广码确定经销商----->以业务员你的推广码优先，找不到再根据经销商推广码去找。 
	 * 
	 * @param promotionCode
	 * @return
	 */
	private Integer getDealerId(String promotionCode) {
		DisDealerAcct disDealerAcct = disDealerAcctService.findByPromotionCode(promotionCode);
		if(CommonUtils.isNotEmpty(disDealerAcct)) {
			Assert.notNull(disDealerAcct.getDealerId(), "推广码业务员没有上级经销商");
			return disDealerAcct.getDealerId();
		}else {
			DisDealer dealer = disDealerService.findByPromotionCode(promotionCode);
			Assert.notNull(dealer, "未查到推广码相关信息，请确认！");
			return dealer.getId();
		}
	}
	private void validateShopParam(RegistTerminalShopParam vo) {
		Assert.notNull(vo.getMobilePhone(), "手机号不能为空");
		DisTerminalShop shop = new DisTerminalShop();
		shop.setMobilePhone(vo.getMobilePhone());
		shop.setStatus(Constants.TERMINAL_SHOP_STATUS_NO_AUDIT);
		if(disTerminalShopDao.selectCount(shop)>0) {
			throw new MessageException(vo.getMobilePhone()+",已经申请还未审核");
		}
		if(!disDealerAcctService.checkPhone(vo.getMobilePhone())) {
			throw new MessageException(vo.getMobilePhone()+",已在平台注册");
		}
		//验证必填项
		Assert.notNull(vo.getPromotionCode(), "推广码不能为空");
		Assert.notNull(vo.getContact(), "联系人不能为空");
		Assert.notNull(vo.getPassWord(), "密码不能为空");
		Assert.notNull(vo.getName(), "店铺名不能为空");
		Assert.notNull(vo.getAddress(), "地址不能为空");
		Assert.notNull(vo.getLat(), vo.getLng(),"经纬度不能为空");
		Assert.notNull(vo.getSmallOpenId(), "小程序openId不能为空");
	}

	/**
	 * 分销app合并分支-------------------------------------
	 */
	
	@Override
	public List<DisTerminalShopData> findByDealerId(Integer dealerId, String enterpriseCode) {
		List<DisTerminalShopData> list = new ArrayList<>();
		List<DisTerminalShopData> realList = disTerminalShopDao.findByDealerId(dealerId,enterpriseCode);
		List<DisTerminalShopData> virtualList = disTerminalShopDao.findByType(Cons.TERMINAL_SHOP_STATUS_VIRTUAL,enterpriseCode);
		if (Utils.isNotEmpty(realList)) {
			for (DisTerminalShopData disTerminalShopData : realList) {
				list.add(disTerminalShopData);
			}
		}
		if (Utils.isNotEmpty(virtualList)) {
			for (DisTerminalShopData disTerminalShopData : virtualList) {
			    list.add(disTerminalShopData);	
			}
		}
		return list;
	}
	
	@Override
	public DisTerminalShopData findById(Integer id, String enterpriseCode) {
		return disTerminalShopDao.findById(id, enterpriseCode);
	}
	
	/**
	 * 分销app合并分支结束-------------------------------------
	 * 
	 */
	
	
	public TerminalShopInfoResponse getLastApplyInfo2(String openId) {
		DisDealerAcctRegAudit audit = distributionAcctRegAuditService.findLastByOpenId(openId);
		if(CommonUtils.isNotEmpty(audit)){
			TerminalShopInfoResponse shopResp = new TerminalShopInfoResponse();
			DisTerminalShop shop = findByCode(audit.getAccount());
			if(CommonUtils.isEmpty(shop)) return null;
			BeanUtils.copyProperties(shop,shopResp);
			shopResp.setPromoteCode(audit.getPromotionCode());
			return shopResp;
		}else{
			List<DisTerminalShopDetail> list = disTerminalShopDetailService.findByOpenId(openId);
			if(CommonUtils.isNotEmpty(list)){
				TerminalShopInfoResponse shopResp = new TerminalShopInfoResponse();
				DisTerminalShop shop = findById(list.get(0).getTerminalShopId());
				if(CommonUtils.isEmpty(shop) || Constants.STATUS_DELETE == shop.getStatus()) return null;
				BeanUtils.copyProperties(shop,shopResp);
				List<DisDealerAcct> accts = disDealerAcctService.findByOpenId(openId);
				if(CommonUtils.isNotEmpty(accts)){
					shopResp.setPromoteCode(accts.get(0).getDealersAcctPromotionCode());
				}
				return shopResp;
				
			}
		}
		return null;
	}

}
